package mn.more.wits.server.dao;

import java.io.Serializable;
import mn.more.wits.client.exception.WitsSecurityException;
import mn.more.wits.server.model.AccountHistory;
import mn.more.wits.server.model.AccountStatus;
import mn.more.wits.server.model.WitsUser;

/**
 * data access object for authentication/authorization related tasks.
 *
 * @author $Author: mikeliucc $
 * @version $Id: AuthProviderDAO.java 5 2008-09-01 12:08:42Z mikeliucc $
 */
public interface AuthProviderDAO extends Serializable {

	// todo: need to externalize!
	String KEY_AUTH = "auth";
	String KEY_FAIL_COUNT = "auth-fail-count";

	/**
	 * attempt to authenticate <code>username</code> with the supplied
	 * <code>password</code>.  If the authentication is successful, an instance of
	 * {@link WitsUser} will be created and returned.  The created {@link WitsUser}
	 * will be filled with the following information: <ul> <li>loginId</li>
	 * <li>roleName (main)</li> <li>roleName (other, if any)</li>
	 * <li>displayName</li> <li>loginTime</li> </ul>
	 * <p/>
	 * It is possible that the caller may further "enrich" the return user object,
	 * for example, with client information or user actions.
	 */
	WitsUser authenticated(String username, String password) throws WitsSecurityException;

	/**
	 * disable the user based on <code>username</code>.  If the targetd user is already disabled, then the method
	 * will simply ignore it -- in other word, this method does NOT toggle user's status.
	 */
	void disable(String username);

	/**
	 * enable the user based on <code>username</code>.  If the targetd user is already enabled, then the method
	 * will simply ignore it -- in other word, this method does NOT toggle user's status.
	 */
	void enable(String username);

	/**
	 * get the account status of <code>username</code>.  The status is based on {@link AccountStatus}.
	 *
	 * @return the current account status
	 * @see AccountStatus
	 */
	AccountStatus getAccountStatus(String username);

	/**
	 * get (if any) the current session information.  A session is defined as the current login session that is
	 * still active (not yet logged out).  In the system, this session should be treated the same as the lastest
	 * successful login attempt which has not yet logged out.  See {@link AccountHistory} for more dtails.
	 * <p/>
	 *
	 * @return null if currently there is no login based on the provided username/HTTP information,
	 *         or a valid {@link AccountHistory} if there is one.
	 * @see AccountHistory
	 */
	AccountHistory getInSessionDetail(String username);

	void changePassword(String username, String newPassword);

	/**
	 * disconnect <code>user</code> object from the "system" - database, memory
	 * object, etc.
	 */
	void invalidate(WitsUser user, String reason);

	/**
	 * disconnect <code>user</code> object from the "system" - database, memory
	 * object, etc.
	 */
	void invalidate(String username, String reason);
}
